[SwiftUI] sheetとfullScreenCoverを出したい
2024.08.21
こんにちは。きんくまです。SwiftUI勉強中です。
モーダル遷移で別画面を表示したいです。
- sheet: 画面の上がぴったり閉じず隙間が開く。下にスワイプすることで画面を閉じることが可能
- fullScreenCover: 画面の上がぴったり隙間なく閉じる。下にスワイプしても画面は閉じられない
参考
Apple公式
Modal presentations
できたもの
コード
ContentView
struct ContentView: View {
@State private var isSheetPresenting = false
@State private var isFullScreenCoverPresenting = false
var body: some View {
VStack {
Spacer()
Button {
isSheetPresenting = true
} label: {
Text("Sheet")
}
.sheet(isPresented: $isSheetPresenting, onDismiss: didDismissSheet) {
SecondView(isModalPresenting: $isSheetPresenting)
}
Spacer()
Button {
isFullScreenCoverPresenting = true
} label: {
Text("FullScreenCover")
}
.fullScreenCover(isPresented: $isFullScreenCoverPresenting, onDismiss: didDismissSheet) {
SecondView(isModalPresenting: $isFullScreenCoverPresenting)
}
Spacer()
}
}
func didDismissSheet() {
print("Sheet dismissed \(isSheetPresenting)")
}
}
開かれる方の画面です
SecondView
struct SecondView: View {
@Binding var isModalPresenting:Bool
var body: some View {
VStack {
Spacer()
Text("Second View")
.foregroundColor(Color.white)
Spacer()
Button {
isModalPresenting = false
} label: {
Text("close")
.foregroundColor(Color.white)
}
Spacer()
}
.frame(maxWidth: .infinity,
maxHeight: .infinity)
.background(Color.blue)
}
}
ここで、iOS 15からはdismissが追加されているのでSecondViewにEnvironmentプロパティを追加すれば親からのModal表示フラグを受け取らなくてもOK
struct SecondView: View {
// このプロパティは不要になる。親の方も修正する必要があるから今回は残している
@Binding var isModalPresenting:Bool
// ここです!
@Environment(\.dismiss) private var dismiss: DismissAction
var body: some View {
VStack {
Spacer()
Text("Second View")
.foregroundColor(Color.white)
Spacer()
Button {
// ここです!
dismiss()
} label: {
Text("close")
.foregroundColor(Color.white)
}
Spacer()
}
.frame(maxWidth: .infinity,
maxHeight: .infinity)
.background(Color.blue)
}
}
そういやPreviewでBindingを設定するときに .constant でもできることを知った
#Preview {
SecondView(isModalPresenting: .constant(true))
}